home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Programmers Heaven 2
/
Programmers Heaven 2.iso
/
files
/
graphics
/
library
/
wgt51_r2.zip
/
WGT5
/
DOC
/
ASM.TXT
next >
Wrap
Text File
|
1996-08-02
|
3KB
|
77 lines
Embedding assembly code into C/C++ programs with Watcom C/C++
Why the _asm keyword is not supported.
Microsoft and Borland have an _asm keyword that is provided with their
code, that allows in-line assembly code to coexist within a C or C++
program. Instead, Watcom uses a #pragma statement to declare a section
of assembly code as an auxiliary function. The developer can specify
parameters to be passed to this code, which registers they go into, and
what registers will be modified. Watcom prefers to use this
implementation, and does not support the _asm implementation, for the
following reasons:
1. The _asm directive does not tell the code generator what registers
have been modified. Therefore, the optimizer cannot exploit maximum
speed advantages. Assembly code is usually written for speed-critical
sections of a program, and having to save and restore all registers when
calling the routine
would add program overhead where it is least desirable. Microsoft and
Borland turn off optimizations around assembly code, but Watcom finds
out which registers are modified to take advantage of maximum
optimization.
2. The pragma statement is much more flexible than the _asm statement.
It allows you to tell the code generator which registers are modified by
the assembly language. It also lets you define 'parameters' to your
routine. For example, using a pragma, you could do something like the
following:
#pragma aux foo= "int 21" parm [ah] [ es bx ];
then
foo( 1, &p );
will automatically put the parameters 1 into ah and &p into es:bx.
You could also call "foo( 2, &q )"
Using the _asm statement, you cannot create generalized inline assembly
like this. The examples would have to be coded separately, as follows:
ASM( mov ah,1 )
ASM( mov es,seg p );
ASM( mov bx,offset p );
ASM( int 21 );
This would only work if 'p' were a static/extern variable, not an auto.
3. #pragma's are quite easy to create. The following creates a DOS
assembly function to set the screen to mode 4:
void mode4( void );
#pragma aux mode4 = \
"mov AH,0", \
"mov AL,4", \
"int 10H" \
modify [ AH, AL ];
This function can be called by using "mode4();" anywhere in a program.
4. The code is kept more portable. All of the machine dependent code is
kept in callable auxiliary functions, with an explicit interface. This
makes the code very easy to port to other processors, which is
especially important with the movement toward RISC-based PCs.
5. Pragmas should generally be needed only for specialty processor-
specific functions, such as "lidt" or "out". In this case, it is easier
to code the instruction once, and call it using a function.
At this time, the #pragma auxiliary functions will only take 128 bytes
of code at a time. For existing programs that use large amounts of
assembly code, it is recommended that this code be put into a separate
assembly language file, and be assembled as a function. The optimizer
will then expand this code inline, and the developer should notice no
difference in performance.